package spe.model.spem;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;


public class MethodPluginImpl extends NodeElementImpl implements MethodPlugin
{	
	private List<MethodContentPackage> methodContentPackages = null;
	private List<ProcessPackage> processPackages = null;
	private MethodPlugin basePlugin = null;
	
	public MethodPluginImpl()
	{
		super();
	}
	
	//get Package
	public List<SPEMElement> getAllNestedElements()
	{
		List<SPEMElement> lst = getChildElements();
		
		if(basePlugin != null)
			lst.add(basePlugin);
		
		return lst;
	}
	
	@Override
	public void initialize()
	{
		methodContentPackages = new ArrayList<MethodContentPackage>();
		processPackages = new ArrayList<ProcessPackage>();
	}

	@Override
	public MethodPlugin getBasePlugin()
	{
		return basePlugin;
	}

	@Override
	public void setBasePlugin(MethodPlugin plugin)
	{
		MethodPlugin old = this.basePlugin;
		//Not good here, please check
		basePlugin = plugin;
		
		firePropertyChange("BasePlugin", old, plugin);
	}

	@Override
	public List<MethodContentPackage> getOwnedMethodContentPackages() 
	{
		return methodContentPackages;
	}

	@Override
	public void setOwnedMethodContentPackages(List<MethodContentPackage> pkgs)
	{
		List<MethodContentPackage> oldValue = this.methodContentPackages;
		methodContentPackages = pkgs;
		for(MethodContentPackage pkg: pkgs)
			pkg.setParent(this);
		
		firePropertyChange("OwnedMethodContentPackages", oldValue, pkgs);
	}

	@Override
	public void addMethodContentPackage(MethodContentPackage pkg) 
	{
		
		if(methodContentPackages == null)
			methodContentPackages = new ArrayList<MethodContentPackage>();
		
		pkg.setParent(this);
		methodContentPackages.add((MethodContentPackage)pkg);
		
		firePropertyChange("MethodContentPackage", null, pkg);
	}

	@Override
	public void removeMethodContentPackage(MethodContentPackage pkg) 
	{
		methodContentPackages.remove(pkg);
		firePropertyChange("MethodContentPackage", pkg, null);
	}

	@Override
	public List<ProcessPackage> getOwnedProcessPackages()
	{
		return processPackages;
	}

	@Override
	public void setOwnedProcessPackages(List<ProcessPackage> pkgs)
	{
		processPackages = pkgs;
		
		for(ProcessPackage pkg: pkgs)
		{
			pkg.setParent(this);
		}
		
		firePropertyChange("OwnedProcessPackages", null, pkgs);
	}

	@Override
	public void addProcessPackage(ProcessPackage pkg) 
	{
		if(processPackages == null)
			processPackages = new ArrayList<ProcessPackage>();
		
		pkg.setParent(this);
		processPackages.add((ProcessPackage)pkg);
		
		firePropertyChange("ProcessPackage", null, pkg);
	}

	@Override
	public void removeProcessPackage(ProcessPackage pkg) 
	{
		if(processPackages == null)
			return;
		
		processPackages.remove(pkg);
		
		firePropertyChange("ProcessPackage", pkg, null);
	}

	@Override
	public List<MethodPluginPackageableElement> getPackageElements()
	{
		List<MethodPluginPackageableElement> lst = new ArrayList<MethodPluginPackageableElement>();
		lst.addAll(methodContentPackages);
		lst.addAll(processPackages);
		return lst;
	}

	@Override
	public List<SPEMElement> getChildElements() 
	{
		List<SPEMElement> lst = new ArrayList<SPEMElement>();
		
		if(methodContentPackages != null)
			lst.addAll(methodContentPackages);
		
		if(processPackages != null)
			lst.addAll(processPackages);
		
		return lst;
	}
	
	@Override
	public void addPropertyChangeListener(PropertyChangeListener listener) 
	{
		propertyChangeSupport.addPropertyChangeListener(listener);
		
		List<SPEMElement> lst = getChildElements();
		for(SPEMElement e: lst)
			e.addPropertyChangeListener(listener);
	}

	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public String toString()
	{
		return String.format("MethodPlugin(%s; id: %s)", super.toString(), id);
	}

	@Override
	public void addChildElement(SPEMElement child) 
	{
		if(ProcessPackage.class.isInstance(child))
			addProcessPackage((ProcessPackage)child);
		
		if(MethodContentPackage.class.isInstance(child))
			addMethodContentPackage((MethodContentPackage)child);
		
	}

	@Override
	public void removeChildElement(SPEMElement child) 
	{
		if(ProcessPackage.class.isInstance(child))
			removeProcessPackage((ProcessPackage)child);
		
		if(MethodContentPackage.class.isInstance(child))
			removeMethodContentPackage((MethodContentPackage)child);
		
	}
}
